/*
 * TriangulateView.java
 */
package triangulate;

import java.awt.Color;
import java.awt.Graphics;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * The application's main frame.
 */
public class TriangulateView extends FrameView
    {

    public TriangulateView(SingleFrameApplication app)
        {
        super(app);

        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener()
            {

            public void actionPerformed(ActionEvent e)
                {
                statusMessageLabel.setText("");
                }
            });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i ++)
            {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
            }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener()
            {

            public void actionPerformed(ActionEvent e)
                {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
                }
            });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener()
            {

            public void propertyChange(java.beans.PropertyChangeEvent evt)
                {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName))
                    {
                    if ( ! busyIconTimer.isRunning())
                        {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                        }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                    }
                else if ("done".equals(propertyName))
                    {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                    }
                else if ("message".equals(propertyName))
                    {
                    String text = (String) (evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                    }
                else if ("progress".equals(propertyName))
                    {
                    int value = (Integer) (evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                    }
                }
            });
        }

    @Action
    public void showAboutBox()
        {
        if (aboutBox == null)
            {
            JFrame mainFrame = TriangulateApp.getApplication().getMainFrame();
            aboutBox = new TriangulateAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
            }
        TriangulateApp.getApplication().show(aboutBox);
        }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings ("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        imagePanel = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        mainPanel.setName("mainPanel"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(triangulate.TriangulateApp.class).getContext().getResourceMap(TriangulateView.class);
        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setName("jButton1"); // NOI18N
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jButton1MousePressed(evt);
            }
        });

        imagePanel.setBorder(new javax.swing.border.MatteBorder(null));
        imagePanel.setName("imagePanel"); // NOI18N

        javax.swing.GroupLayout imagePanelLayout = new javax.swing.GroupLayout(imagePanel);
        imagePanel.setLayout(imagePanelLayout);
        imagePanelLayout.setHorizontalGroup(
            imagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 409, Short.MAX_VALUE)
        );
        imagePanelLayout.setVerticalGroup(
            imagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 321, Short.MAX_VALUE)
        );

        jButton2.setText(resourceMap.getString("jButton2.text")); // NOI18N
        jButton2.setName("jButton2"); // NOI18N
        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jButton2MousePressed(evt);
            }
        });

        jButton3.setText(resourceMap.getString("jButton3.text")); // NOI18N
        jButton3.setName("jButton3"); // NOI18N
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        jButton4.setText(resourceMap.getString("jButton4.text")); // NOI18N
        jButton4.setName("jButton4"); // NOI18N
        jButton4.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                exportClicked(evt);
            }
        });

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                        .addComponent(jButton3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 130, Short.MAX_VALUE)
                        .addComponent(jButton4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton1))
                    .addComponent(imagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(imagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton3)
                    .addComponent(jButton2)
                    .addComponent(jButton4))
                .addContainerGap())
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(triangulate.TriangulateApp.class).getContext().getActionMap(TriangulateView.class, this);
        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 435, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 251, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

    //plot naive triangulation
    private void jButton1MousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MousePressed
        SVGUtils.drawPolygons( getGraphics(), getComplexPolys( 800, 480 ) );
    }//GEN-LAST:event_jButton1MousePressed

    public static ArrayList<ColoredPolygon> getComplexPolys( int width, int height) {
        ArrayList<ColoredPolygon> pols = new ArrayList<ColoredPolygon>();
        try
            {
            File file = new File("input.svg");
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);
            doc.getDocumentElement().normalize();
            NodeList nodeLst = doc.getElementsByTagName("path");
            Color color;
            ColoredPolygon p = null;
            for (int s = 0; s < nodeLst.getLength(); s ++ )
                {
                Node fstNode = nodeLst.item(s);
                if (fstNode.getNodeType() == Node.ELEMENT_NODE)
                    {
                    Element fstElmnt = (Element) fstNode;
                    color = SVGUtils.parseColorFromStyle(fstElmnt.getAttribute("style"));
                    //  System.out.println("node:"+fstElmnt.getAttribute("style"));
                    //          System.out.println("node:" + fstElmnt.getAttribute("d"));
                    p = SVGUtils.parseD(fstElmnt.getAttribute("d"), width, height);
                    p.color = color;
                    p.originalStyle = fstElmnt.getAttribute("style");
                    pols.add(p);
                    }
                }
            }
        catch (SAXException ex)
            {
            Logger.getLogger(TriangulateView.class.getName()).log(Level.SEVERE, null, ex);
            }
        catch (IOException ex)
            {
            Logger.getLogger(TriangulateView.class.getName()).log(Level.SEVERE, null, ex);
            }        catch (ParserConfigurationException ex)
            {
            Logger.getLogger(TriangulateView.class.getName()).log(Level.SEVERE, null, ex);
            }
        return pols;
    }

    public static ArrayList<ColoredPolygon> getPoly() {

        ArrayList<ColoredPolygon> pols = new ArrayList<ColoredPolygon>();
        ColoredPolygon pol = new ColoredPolygon();
        pol.addPoint(2, 50);
        pol.addPoint(30, 5);
        pol.addPoint(80, 40);
        pol.addPoint(25, 100);
//        pol.addPoint(60, 80);
        pol.addPoint(100, 120);
        pol.addPoint(20, 110);
        pols.add(pol);
        return pols;
    }

    private Graphics getGraphics() {
        return this.imagePanel.getGraphics();
    }

    //triangulate
    private void jButton2MousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton2MousePressed
        FileOutputStream os = null;
        try
            {
            ArrayList< ColoredPolygon > pols = cut( getComplexPolys( 800, 480 ) );
            ColoredPolygon pol;

            System.out.println("export");
            os = new FileOutputStream("output.svg");
            String head;

            head = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n<svg width='800' height='480'>\n<g>\n";
            os.write(head.getBytes());
            for ( int c = 0; c < pols.size(); ++c ) {
                pol = pols.get( c );
                head = pol.getSVGString();
                os.write(head.getBytes());
            }


            head="</g>\n</svg>";
            os.write(head.getBytes());

            os.close();
            }
        catch ( Exception ex )
            {
            Logger.getLogger(TriangulateView.class.getName()).log(Level.SEVERE, null, ex);
            }
        finally
            {
            try
                {
                os.close();
                }
            catch (Exception ex)
                {
                Logger.getLogger(TriangulateView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
    }//GEN-LAST:event_jButton2MousePressed

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
         getGraphics().clearRect(0, 0, imagePanel.getWidth(), imagePanel.getHeight());
    }//GEN-LAST:event_jButton3ActionPerformed

    private void exportClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_exportClicked
        FileOutputStream os = null;
        try
            {
            ArrayList< ColoredPolygon > pols = cut( getComplexPolys( 800, 480 ) );
            ColoredPolygon pol;

            System.out.println("export");
//            os = new FileOutputStream("output.svg");
            os = new FileOutputStream("output.bin");
//            String head;
            
//            head = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n<svg width='800' height='480'>\n<g>\n";
//            os.write(head.getBytes());
              os.write( pols.size() );
            for ( int c = 0; c < pols.size(); ++c ) {
                pol = pols.get( c );
//                head = pol.getSVGString();
                pol.writePath( os );
//                os.write(head.getBytes());
            }


//            head="</g>\n</svg>";
//            os.write(head.getBytes());

            os.close();
            }
        catch ( Exception ex )
            {
            Logger.getLogger(TriangulateView.class.getName()).log(Level.SEVERE, null, ex);
            }
        finally
            {
            try
                {
                os.close();
                }
            catch (Exception ex)
                {
                Logger.getLogger(TriangulateView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
    }//GEN-LAST:event_exportClicked


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel imagePanel;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    // End of variables declaration//GEN-END:variables
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private JDialog aboutBox;
   
//=============================================================================
    private ArrayList< ColoredPolygon > cut( ArrayList<ColoredPolygon> pols )
        {
        ArrayList< ColoredPolygon > toReturn = new ArrayList< ColoredPolygon >();
        Graphics graphics = this.imagePanel.getGraphics();
        int[] xi;
        int[] xv;
        System.out.println("====Cut====");
        ColoredPolygon proc;
        ColoredPolygon proc1;
        ColoredPolygon proc2;
        ArrayList< ColoredPolygon > proc3;
        ColoredPolygon proc4;
        ArrayList< ColoredPolygon > proc5;
        ColoredPolygon proc6;
        int n = 0;
        int c;
        int f;
        graphics.setColor(Color.red);
        ///para cada poligono
            for ( int d = 0; d < pols.size(); ++d ) {
                System.out.println("d:" + d );
                proc = pols.get(d);

                xv = new int[ proc.npoints ];
                xi = new int[ proc.npoints ];


                for ( int e = 0; e < proc.npoints; e++ ) {
                    xv[ e ] = proc.xpoints[ e ];
                    xi[ e ] = e;
                }

                SVGUtils.order( xv, xi );


                for (int h = 0; h < proc.npoints ; h++)
                    {
                        c = xi[ h ];
                        f = xi[ ( h + 1 ) % proc.npoints ];
                        System.out.println( xv[h] + " " + c + "=[" + proc.xpoints[ c ] + "," + proc.xpoints[ f ] + "]");
                        graphics.setColor(new Color((int) (255 * Math.random()), (int) (255 * Math.random()), (int) (255 * Math.random())));
                        proc1 = SVGUtils.CullXNoLessThan(proc.xpoints[c], proc);
                        proc2 = SVGUtils.CullXNoMoreThan(proc.xpoints[ f ], proc1);
                        proc3 = decomposeIntoMonotones( proc2 );


                        for ( int i = 0; i < proc3.size(); ++i ) {
                            proc4 = proc3.get( i );
                            SVGUtils.drawPolygon(graphics, proc4, 0, 0 );
                            graphics.setColor(new Color((int) (255 * Math.random()), (int) (255 * Math.random()), (int) (255 * Math.random())));
                            
                            proc5 = triangulate( proc4 );

                            for ( int j = 0; j < proc5.size(); ++j ) {
                                proc6 = proc5.get( j );
                                toReturn.add( proc6 );
                                SVGUtils.drawPolygon(graphics, proc6, 0, 0 );
                                graphics.setColor(new Color((int) (255 * Math.random()), (int) (255 * Math.random()), (int) (255 * Math.random())));
                            }

                        }
                    }
            }
        
            return toReturn;
        }
//=============================================================================
    /**
     *
     * @param tpol HOT!
     * @return
     */
    ColoredPolygon simplify(ColoredPolygon tpol, int span1, int span2)
        {
        ColoredPolygon ano = new ColoredPolygon();
            {
            int smallerIndex = 0;
            int smallerValue = 0;
            int biggerIndex = tpol.npoints;
            int biggerValue = tpol.ypoints[tpol.npoints - 1];

            for (int c = 0; c < tpol.npoints;  ++ c)
                {
                if (tpol.xpoints[c] == span1)
                    {
                    if (tpol.ypoints[c] < smallerValue)
                        {
                        smallerIndex = c;
                        smallerValue = tpol.ypoints[c];
                        }

                    if (tpol.xpoints[c] > biggerValue)
                        {
                        biggerIndex = c;
                        biggerValue = tpol.ypoints[c];
                        }
                    }
                }

            ano.addPoint(span1, smallerValue);
            ano.addPoint(span1, biggerValue);
            }
            {
            int smallerValue = 0;
            int biggerValue = tpol.ypoints[tpol.npoints - 1];

            for (int c = 0; c < tpol.npoints;  ++ c)
                {
                if (tpol.xpoints[c] == span2)
                    {
                    if (tpol.ypoints[c] < smallerValue)
                        {
                        smallerValue = tpol.ypoints[c];
                        }

                    if (tpol.xpoints[c] > biggerValue)
                        {
                        biggerValue = tpol.ypoints[c];
                        }
                    }
                }
            ano.addPoint(span1, biggerValue);
            ano.addPoint(span1, smallerValue);


            }

        return ano;
        }
//=============================================================================
     private ArrayList<ColoredPolygon> triangulate( ColoredPolygon proc2)
        {
        ArrayList<ColoredPolygon> toReturn = new ArrayList<ColoredPolygon>();
        ColoredPolygon pol;
        for ( int c = 0 ; c < proc2.npoints - 2; ++c)
            {
                pol = new ColoredPolygon();
                pol.color = proc2.color;
                pol.originalStyle = proc2.originalStyle;
                toReturn.add( pol );
                pol.addPoint(proc2.xpoints[0], proc2.ypoints[0]);
                pol.addPoint(proc2.xpoints[c + 1], proc2.ypoints[c + 1]);
                pol.addPoint(proc2.xpoints[c + 2], proc2.ypoints[c + 2]);
            }

        return toReturn;
        }

    private ArrayList<ColoredPolygon> decomposeIntoMonotones(ColoredPolygon proc2)
        {
        ColoredPolygon p;
        int v1x;
        int v1y;
        int v2x;
        int v2y;
        int v3x;
        int v3y;
        int vx;
        int vy;
        int c = 0;
        int pass = 0;
        ArrayList<ColoredPolygon> toReturn = new ArrayList<ColoredPolygon>();

        while (proc2.npoints > 4)
            {
            pass++;

            p = new ColoredPolygon();
            p.color = proc2.color;
            p.originalStyle = proc2.originalStyle;
            c = 0;
            v1x = proc2.xpoints[ 0];
            v1y = proc2.ypoints[ 0];

            vx = v1x;
            vy = v1y;

            while (c < proc2.npoints)
                {

                vx = proc2.xpoints[c];
                vy = proc2.ypoints[c];


                if (vx != v1x)
                    {
                    break;
                    }

                v1x = vx;
                v1y = vy;

                c ++;
                }

            p.addPoint(v1x, v1y);

            while (c < proc2.npoints)
                {

                vx = proc2.xpoints[c];
                vy = proc2.ypoints[c];


                if (vx != v1x)
                    {
                    break;
                    }
                c ++;
                }

            v2x = vx;
            v2y = vy;
            v3x = vx;
            v3y = vy;
            p.addPoint(v2x, v2y);

            while (c < proc2.npoints)
                {

                vx = proc2.xpoints[c];
                vy = proc2.ypoints[c];


                if (vx != v2x)
                    {
                    break;
                    }

                v3x = vx;
                v3y = vy;

                c ++;
                }

            p.addPoint(v3x, v3y);
            p.addPoint(vx, vy);

            toReturn.add(p);

            p = new ColoredPolygon();
            p.color = proc2.color;
            p.originalStyle = proc2.originalStyle;
            while (c < proc2.npoints)
                {
                vx = proc2.xpoints[c];
                vy = proc2.ypoints[c];
                p.addPoint(vx, vy);
                c ++;
                }

            proc2 = p;
            }

        toReturn.add(proc2);

        return toReturn;
        }
//=============================================================================
    }
